package com.mjk.manager.centerconf.conf;

import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;

import com.mjk.common.base.scope.BeanRefreshScope;
import com.mjk.common.core.redis.datatype.RedisHashUtils;
import com.mjk.common.tools.springextend.BeeApplicationListener;
import lombok.Getter;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.data.redis.core.RedisTemplate;


@Configuration
@ConditionalOnProperty(name = "bee.redis", havingValue = "true")
public class CenterConf
		implements BeanDefinitionRegistryPostProcessor, BeeApplicationListener, BeanFactoryPostProcessor {
	/**
	 * 通知键
	 */
	public static final String CONFIGURATION_KEY = "conf";
	/**
	 * 剪值内容
	 */
	public static final String CONFIGURATION_CONTENT_KEY = "conf_content";

	public static final String APPLICATION_SOURCE_NAME = "applicationConfig: [classpath:/application.properties]";

	public static final String THRIDAPPLICATION_SOURCE_NAME = "class path resource [thirdparty.properties]";
	// 排除的 配置属性前缀
	private static final String[] excludes = new String[] { "bee.mybatis", "spring" };

	@Getter
	private AbstractApplicationContext context;

	@Getter
	private Map<String, Object> map;

	BeanDefinitionRegistry registry;

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        beanFactory.registerScope(BeanRefreshScope.SCOPE_REFRESH, BeanRefreshScope.getInstance());
	}

	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		this.registry = registry;
	}

	@SuppressWarnings("unchecked")
	@Override
	public void doApplicationEvent(ContextRefreshedEvent event) {
		context = (AbstractApplicationContext) event.getApplicationContext();
		RedisTemplate redisTemplate = (RedisTemplate) context.getBean("redisTemplate");
		MutablePropertySources sources = context.getEnvironment().getPropertySources();
		if(!sources.contains(THRIDAPPLICATION_SOURCE_NAME)) {
			return;
		}
		map = (Map<String, Object>) Objects.requireNonNull(sources.get(THRIDAPPLICATION_SOURCE_NAME)).getSource();
        for (Entry<String, Object> entry : map.entrySet()) {
			boolean isExclude = false;
			for (String exclude : excludes) {
				if (entry.getKey().startsWith(exclude)) {
					isExclude = true;
					break;
				}
			}
			if (isExclude) {
				continue;
			}
			if (!RedisHashUtils.exists(redisTemplate, CONFIGURATION_CONTENT_KEY, entry.getKey())) {
				RedisHashUtils.set(redisTemplate, CONFIGURATION_CONTENT_KEY, entry.getKey(),entry.getValue().toString());
			}
		}
	}

}
